package com.xinxin.base.util.legacy;

import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 类型转换问题，可参考
 * http://stackoverflow.com/questions/19431234/converting-between-java-time-localdatetime-and-java-util-date
 */
public final class TimeUtils {
    private static final ZoneOffset ZONE_OFFSET = ZoneOffset.ofHours(8); // 北京时间 东8区

    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DATE_TIME_T_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");

    private static final ZoneId CN_ZONE_ID = ZoneId.of("Asia/Shanghai");

    public static Timestamp localDateTime2Timestamp(LocalDateTime localDateTime) {
        Instant instant = localDateTime.toInstant(ZONE_OFFSET);
        return Timestamp.from(instant);
    }

    public static LocalDateTime timestamp2LocalDateTime(Timestamp timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp.getTime());
        return LocalDateTime.ofInstant(instant, ZONE_OFFSET);
    }

    public static LocalDateTime now() {
        return LocalDateTime.now().withNano(0);
    }

    public static long localDateTime2Millis(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZONE_OFFSET).toEpochMilli();
    }

    public static LocalDateTime millis2LocalDateTime(long millis) {
        Instant instant = Instant.ofEpochMilli(millis);
        return LocalDateTime.ofInstant(instant, ZONE_OFFSET);
    }

    public static long localDateTime2Seconds(LocalDateTime localDateTime) {
        return localDateTime2Millis(localDateTime) / 1000;
    }

    public static LocalDateTime seconds2LocalDateTime(long seconds) {
        return millis2LocalDateTime(seconds * 1000);
    }

    public static long currentTimestampInS() {
        return currentTimestampInMillis() / 1000;
    }

    public static long currentTimestampInMillis() {
        return System.currentTimeMillis();
    }

    public static LocalDateTime min(LocalDateTime t1, LocalDateTime t2) {
        return t1.isBefore(t2) ? t1 : t2;
    }

    public static LocalDateTime max(LocalDateTime t1, LocalDateTime t2) {
        return t1.isAfter(t2) ? t1 : t2;
    }

    public static LocalDateTime parse(String timeText) {
        if (StringUtils.isBlank(timeText)) {
            return null;
        }
        if (timeText.contains("T")) {
            return LocalDateTime.parse(timeText.replace("T", ""), DATE_TIME_FORMATTER);
        }
        return LocalDateTime.parse(timeText, DATE_TIME_FORMATTER);
    }

    public static String format(LocalDateTime time) {
        return time.format(DATE_TIME_FORMATTER);
    }

    /**
     * 获取当前至第二天凌晨所需秒数
     * @return
     */
    public static int getSecondsFromNowToTomorrow() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime nextDay = now.toLocalDate().plusDays(1).atStartOfDay();
        int seconds = (int)(localDateTime2Seconds(nextDay) - localDateTime2Seconds(now));
        final int oneDaySeconds = 3600 * 24;
        return Math.min(seconds, oneDaySeconds);
    }

//    public static LocalDateTime parseFromTextParam(String beginTimeText) {
//        return LocalDateTime.parse(beginTimeText);
//    }

    public static LocalDateTime parseZonedTime(String zonedTimeText) {
        ZonedDateTime zonedDateTime = ZonedDateTime.parse(zonedTimeText);
        return zonedDateTime.withZoneSameInstant(CN_ZONE_ID).toLocalDateTime();
    }

    public static long pastMillis(LocalDateTime time) {
        return localDateTime2Millis(LocalDateTime.now()) - localDateTime2Millis(time);
    }

    public static LocalDate thisMonth() {
        return now().toLocalDate().withDayOfMonth(1);
    }

    public static long getDiffHours(LocalDateTime t1, LocalDateTime t2) {
        final long m1 = TimeUtils.localDateTime2Millis(t1);
        final long m2 = TimeUtils.localDateTime2Millis(t2);
        final long diff = Math.abs(m2 - m1);
        return TimeUnit.MILLISECONDS.toHours(diff);
    }

	public static void main(String[] args) {
    	LocalDateTime now = LocalDateTime.now();
		long t  = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
		System.out.println(t);
		t  = localDateTime2Millis(now);
		System.out.println(t);
	}

}
